package com.common.base.utils

import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.util.Log
import androidx.activity.result.ActivityResultLauncher
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader


/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：3/4/2023
 *
 * 描述：
 *
 * 修订历史：
 *
 */
class PermissionUtil {

    private val PERMISSION_SETTING_FOR_RESULT = 11114
    private val TAG = "PermissionUtil"
    private var mContext: Activity? = null

    //自己的项目包名
    private var packageName = ""

    constructor(context: Activity?) {
        mContext = context
        packageName = mContext?.packageName.toString()
    }

    fun goToSetting(launcherResult: ActivityResultLauncher<Intent>? = null) {
        goIntentSetting(launcherResult)
    }

    private fun goIntentSetting(launcherResult: ActivityResultLauncher<Intent>? = null) {
        try {
            val intent = Intent()
            intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
            intent.addCategory(Intent.CATEGORY_DEFAULT)
            intent.data = Uri.parse("package:" + mContext?.packageName)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
            intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
            mContext?.apply {
                if (launcherResult == null) {
                    startActivityForResult(intent, PERMISSION_SETTING_FOR_RESULT)
                } else {
                    launcherResult.launch(intent)
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            val name: String = Build.MANUFACTURER
            Log.e(TAG, "jumpPermissionPage --- name : $name")
            when (name) {
                "HUAWEI" -> goHuaWeiMainager()
                "vivo" -> goVivoMainager()
                "OPPO" -> goOppoMainager()
                "Coolpad" -> goCoolpadMainager()
                "Meizu" -> goMeizuMainager()
                "Xiaomi" -> goXiaoMiMainager()
                "Sony" -> goSonyMainager()
                "LG" -> goLGMainager()
                else -> systemConfig()
            }
        }
    }

    private fun goLGMainager() {
        try {
            val intent = Intent(packageName)
            val comp = ComponentName(
                "com.android.settings",
                "com.android.settings.Settings\$AccessLockSummaryActivity"
            )
            intent.component = comp
            mContext?.apply {
                startActivityForResult(intent, PERMISSION_SETTING_FOR_RESULT)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            systemConfig()
        }
    }

    private fun goSonyMainager() {
        try {
            val intent = Intent(packageName)
            val comp = ComponentName("com.sonymobile.cta", "com.sonymobile.cta.SomcCTAMainActivity")
            intent.component = comp
            mContext?.apply {
                startActivityForResult(intent, PERMISSION_SETTING_FOR_RESULT)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            systemConfig()
        }
    }

    private fun goHuaWeiMainager() {
        try {
            val intent = Intent(packageName)
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            val comp = ComponentName(
                "com.huawei.systemmanager",
                "com.huawei.permissionmanager.ui.MainActivity"
            )
            intent.component = comp
            mContext?.apply {
                startActivityForResult(intent, PERMISSION_SETTING_FOR_RESULT)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            systemConfig()
        }
    }

    private fun goXiaoMiMainager() {
        val rom = miuiVersion
        Log.e(TAG, "goMiaoMiMainager --- rom : $rom")
        val intent = Intent()
        if ("V6" == rom || "V7" == rom) {
            intent.action = "miui.intent.action.APP_PERM_EDITOR"
            intent.setClassName(
                "com.miui.securitycenter",
                "com.miui.permcenter.permissions.AppPermissionsEditorActivity"
            )
            intent.putExtra("extra_pkgname", packageName)
            mContext?.apply {
                startActivityForResult(intent, PERMISSION_SETTING_FOR_RESULT)
            }
        } else if ("V8" == rom || "V9" == rom) {
            intent.action = "miui.intent.action.APP_PERM_EDITOR"
            intent.setClassName(
                "com.miui.securitycenter",
                "com.miui.permcenter.permissions.PermissionsEditorActivity"
            )
            intent.putExtra("extra_pkgname", packageName)
            mContext?.apply {
                startActivityForResult(intent, PERMISSION_SETTING_FOR_RESULT)
            }
        } else {
            systemConfig()
        }
    }

    private fun goMeizuMainager() {
        try {
            val intent = Intent("com.meizu.safe.security.SHOW_APPSEC")
            intent.addCategory(Intent.CATEGORY_DEFAULT)
            intent.putExtra("packageName", packageName)
            mContext?.apply {
                startActivityForResult(intent, PERMISSION_SETTING_FOR_RESULT)
            }
        } catch (localActivityNotFoundException: ActivityNotFoundException) {
            localActivityNotFoundException.printStackTrace()
            systemConfig()
        }
    }

    /**
     * 系统设置界面
     */
    private fun systemConfig() {
        val intent = Intent(Settings.ACTION_SETTINGS)
        mContext?.apply {
            startActivityForResult(intent, PERMISSION_SETTING_FOR_RESULT)
        }
    }

    private fun goOppoMainager() {
        doStartApplicationWithPackageName("com.coloros.safecenter")
    }

    /**
     * doStartApplicationWithPackageName("com.yulong.android.security:remote")
     * 和Intent open = getPackageManager().getLaunchIntentForPackage("com.yulong.android.security:remote");
     * startActivity(open);
     * 本质上没有什么区别，通过Intent open...打开比调用doStartApplicationWithPackageName方法更快，也是android本身提供的方法
     */
    private fun goCoolpadMainager() {
        doStartApplicationWithPackageName("com.yulong.android.security:remote")
    }

    private fun goVivoMainager() {
        doStartApplicationWithPackageName("com.bairenkeji.icaller")
    }

    /**
     * 此方法在手机各个机型设置中已经失效
     *
     * @return
     */
    private fun getAppDetailSettingIntent(): Intent {
        val localIntent = Intent()
        localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        localIntent.action = "android.settings.APPLICATION_DETAILS_SETTINGS"
        localIntent.data = Uri.fromParts("package", mContext?.packageName, null)
        return localIntent
    }

    private fun doStartApplicationWithPackageName(packagename: String) {
        // 通过包名获取此APP详细信息，包括Activities、services、versioncode、name等等
        var packageinfo: PackageInfo? = null
        try {
            packageinfo = mContext?.packageManager?.getPackageInfo(packagename, 0)
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        if (packageinfo == null) {
            return
        }
        // 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent
        val resolveIntent = Intent(Intent.ACTION_MAIN, null)
        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER)
        resolveIntent.setPackage(packageinfo.packageName)
        // 通过getPackageManager()的queryIntentActivities方法遍历
        val resolveinfoList: List<ResolveInfo> =
            mContext?.packageManager?.queryIntentActivities(resolveIntent, 0) as List<ResolveInfo>
        Log.e("PermissionPageManager", "resolveinfoList" + resolveinfoList.size)
        for (i in resolveinfoList.indices) {
            Log.e(
                "PermissionPageManager",
                resolveinfoList[i].activityInfo.packageName + resolveinfoList[i].activityInfo.name
            )
        }
        val resolveinfo: ResolveInfo = resolveinfoList.iterator().next()
        if (resolveinfo != null) {
            // packageName参数2 = 参数 packname
            val packageName: String = resolveinfo.activityInfo.packageName
            // 这个就是我们要找的该APP的LAUNCHER的Activity[组织形式：packageName参数2.mainActivityname]
            val className: String = resolveinfo.activityInfo.name
            // LAUNCHER Intent
            val intent = Intent(Intent.ACTION_MAIN)
            intent.addCategory(Intent.CATEGORY_LAUNCHER)
            // 设置ComponentName参数1:packageName参数2:MainActivity路径
            val cn = ComponentName(packageName, className)
            intent.setComponent(cn)
            try {
                mContext?.apply {
                    startActivityForResult(intent, PERMISSION_SETTING_FOR_RESULT)
                }
            } catch (e: Exception) {
                systemConfig()
                e.printStackTrace()
            }
        }
    }

    companion object {
        private var Instance: PermissionUtil? = null
        fun getInstance(context: Activity?): PermissionUtil? {
            if (Instance == null) {
                Instance = PermissionUtil(context)
            }
            return Instance
        }

        private val miuiVersion: String?
            private get() {
                val propName = "ro.miui.ui.version.name"
                val line: String
                var input: BufferedReader? = null
                try {
                    val p = Runtime.getRuntime().exec("getprop $propName")
                    input = BufferedReader(InputStreamReader(p.inputStream), 1024)
                    line = input.readLine()
                    input.close()
                } catch (ex: IOException) {
                    ex.printStackTrace()
                    return null
                } finally {
                    try {
                        input?.close()
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }
                }
                return line
            }
    }
}